
if(!window["MUI"]) window["MUI"]={};

MUI.Grid = new Class({
    initialize:function(data, options){
	if($type(data)=='element'){
	    this.el = data;
	    data = MUI.Grid.parseTable(data);
	}
	this.def = data;
    },
    
    render:function(){
	var rendered = MUI.Grid.toTable(this.def);
	if(this.el){
	    this.el = rendered.replaces(this.el);
	}else{
	    this.el = rendered;
	}
	return this.el;
    }
});

MUI.Grid.getInstance = function(data, types, options){
    if(types==null || types.length==0){
	return new MUI.Grid(data, options);
    }else{
	var CustomGrid = new Class({Extends:MUI.Grid});
	types.each(function(type){
	    CustomGrid = CustomGrid.implement(MUI.Grid.Types[type]);
	});
	return new CustomGrid(data, options);
    }
}

MUI.Grid.parseTable = function(oTable){
    oTable = $(oTable);
    var table = {columns:[], data:[]};
    var columns = oTable.getElements("thead th");
    columns.each(function(col){
	table.columns.push({
	    label: col.innerHTML,
	    type: col.getProperty("type") || ""
	});
    });
    
    var rows = oTable.getElements("tbody tr");
    rows.each(function(row){
	var aRow = [];
	row.getElements("td").each(function(cell){
	    aRow.push(cell.innerHTML);
	});
	table.data.push(aRow);
    });

    return table;
}

MUI.Grid.toTable = function(oTable){
    //alert(Json.toString(oTable));
    var table = new Element("table");
    var thead = new Element("thead").injectInside(table);
    oTable.columns.each(function(col){
	new Element("th")
	    .setProperty("type", col.type || "")
	    .appendText(col.label)
	    .injectInside(thead);
    });
    MUI.Grid.renderBody(oTable.data).injectInside(table);
    return table;
}

MUI.Grid.renderBody = function(data){
    var tbody = new Element("tbody");
    data.each(function(aRow){
	var row = new Element("tr").injectInside(tbody);
	aRow.each(function(cell){
	    new Element("td").appendText(cell).injectInside(row);
	});
    });
    return tbody;
}


MUI.Grid.Types = {};
MUI.Grid.Types.Sortable = {
    
    sort:function(index, desc){
	if(index>this.def.columns.length) return;
	var type = this.def.columns[index].type;
	if(type=="") return;
	var sortAlgorithm = this._getAlgorithm(type);
	this.def.data.sort(function(a, b){
	    return (desc?-1:1)*sortAlgorithm(a, b, index);
	}.bind(this));
    },
    
    render:function(){
	var table = this.parent();
	var grid = this;
	table.getElements("thead th").each(function(th, index){
	    th.desc = false;
	    th.addEvent("click", function(e){
		grid.sort(index, this.desc);
                MUI.Grid.renderBody(grid.def.data).replaces(this.getParent().getParent().getElement("tbody"));
		th.desc = !th.desc;
		new Event(e).stop();
	    });
	});
	return table;
    },
    
    _getAlgorithm:function(type){
	switch(type){
	    case 'integer':
		return this.__integerSort.bind(this);
		break;
	    case 'datetime':
                
		return this.__datetimeSort.bind(this);
		break;
	    case 'string':
	    default:
		return this.__stringSort.bind(this);
		break;	    
	}
    },
    
    __compareValues:function(a, b){
	return a<b?-11:(a>b?1:0);
    },
    
    __stringSort:function(a, b, index){
	return this.__compareValues(a[index], b[index]);	
    },
    
    __integerSort:function(a, b, index){
	return this.__compareValues(a[index]*1, b[index]*1);
    },
    
    __datetimeSort:function(a, b, index){
	return this.__compareValues(a[index].toDate(), b[index].toDate());
    }
}

String.prototype.toDate = function(){
    var parts = this.split("-");
    return new Date(parts[0]*1, parts[1]*1-1, parts[2]*1);
}
Date.prototype.toDate = function(){ return this; };
Date.prototype.toString = function(){
    return [this.getFullYear(), "-", this.getMonth()+1, "-", this.getDate()].join("");
}

Element.implement({
    asGrid:function(types, options){
	if(this.get('tag')=="table"){
	    var grid = MUI.Grid.getInstance(this, types, options);
	    grid.render();
	    return grid;
	}
	return null;
    }
});